﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using HP.Cachalote.DataModels;
using HP.Cachalote.Services.Interfaces;
using HP.Cachalote.WPF.Model;
using HP.Cachalote.WPF.Shared;

namespace HP.Cachalote.WPF.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class TodoLabelTreeViewModel : MyViewModelBase
    {
        public const string SelectToShowRelatedTodoItemsMessageToken = "SelectToShowRelatedTodoItems";

        private ITodoLabelService _todoLabelService;

        /// <summary>
        /// Initializes a new instance of the LabelTreeViewModel class.
        /// </summary>
        public TodoLabelTreeViewModel(IDataService dataService) : base(dataService)
        {
            try
            {
                _todoLabelService = ServiceFactory.CreateLabelService();
                LoadLabelList();
            }
            catch (System.Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// The <see cref="LabelList" /> property's name.
        /// </summary>
        public const string LabelListPropertyName = "LabelList";

        private ObservableCollection<TodoLabelTreeViewItemViewModel> _labelList;

        /// <summary>
        /// Sets and gets the LabelList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<TodoLabelTreeViewItemViewModel> LabelList
        {
            get
            {
                return _labelList;
            }

            set
            {
                if (_labelList == value)
                {
                    return;
                }

                RaisePropertyChanging(LabelListPropertyName);
                _labelList = value;
                RaisePropertyChanged(LabelListPropertyName);
            }
        }

        private void LoadLabelList()
        {
            //Load entire tree at once time
            //LabelList = _todoLabelService.GetHierarchicalLabelList();

            //Load root label and its sub-labels
            //LabelList = (from label in _todoLabelService.Filter(label => label.Parent == null).OrderBy(label => label.OrderIndex)
            //             select new TodoLabelTreeViewItemViewModel(CurrentDataService)
            //             {
            //                 ID = label.ID,
            //                 Parent = null,
            //                 Name = label.Name,
            //                 OrderIndex = label.OrderIndex,
            //                 SubLabels = (from subLabel in _todoLabelService.Filter(subLabel => subLabel.Parent == label).OrderBy(l => l.OrderIndex)
            //                              select new TodoLabelTreeViewItemViewModel(CurrentDataService)
            //                              {
            //                                  ID = subLabel.ID, 
            //                                  //Parent = label,
            //                                  Name = subLabel.Name,
            //                                  OrderIndex = subLabel.OrderIndex
            //                              }).ToList()
            //             }).ToList();

            //Get all root labels
            LabelList = new ObservableCollection<TodoLabelTreeViewItemViewModel>
                (from label in _todoLabelService.Filter(label => label.Parent == null).OrderBy(label => label.OrderIndex)
                 select new TodoLabelTreeViewItemViewModel(CurrentDataService)
                 {
                     ID = label.ID,
                     Parent = null,
                     Name = label.Name,
                     OrderIndex = label.OrderIndex
                 });

            foreach (var item in LabelList)
            {
                item.PeerLabels = LabelList;
                item.LoadRelatedTodoItemCount();
            }

            //Get the first level labels of root label
            foreach (var label in LabelList)
            {
                label.SubLabels = new ObservableCollection<TodoLabelTreeViewItemViewModel>
                    (from subLabel in
                         _todoLabelService.Filter(subLabel => subLabel.Parent != null && subLabel.Parent.ID == label.ID).OrderBy(l => l.OrderIndex)
                     select new TodoLabelTreeViewItemViewModel(CurrentDataService)
                     {
                         ID = subLabel.ID,
                         Parent = label,
                         Name = subLabel.Name,
                         OrderIndex = subLabel.OrderIndex
                     });

                foreach (var item in label.SubLabels)
                {
                    item.PeerLabels = label.SubLabels;
                    item.LoadRelatedTodoItemCount();
                }
            }
        }
    }
}